package com.niit.blog.util;

import com.niit.blog.entity.Dto.SortDto;
import lombok.extern.slf4j.Slf4j;
import org.omg.PortableInterceptor.INACTIVE;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Component
@Slf4j
public class RedisUtil {
    private static final String zsetKey = "BLOG-SORT_VIEWS" ;
    @Resource
    private RedisTemplate redisTemplate;

//返回排行榜数据
    public List<SortDto> sortByViews(List<SortDto> list) {
        HashMap<Integer, Long> objectObjectHashMap = new HashMap<>();
        for (SortDto sortDto : list) {
            objectObjectHashMap.put(sortDto.getBlogId(), sortDto.getBlogViews());
        }
        //先判断键是否存在，随后进行初始化和实例化，抽取成一个方法进行
        if (!keyExists(zsetKey)) {
            if (prepareData(zsetKey,objectObjectHashMap)) {
                log.info("初始化数据成功");
                System.out.println("初始化数据成功");
                List<SortDto> sortDtos = querySortByViews(zsetKey);
                log.info("排序的数据为：{}",sortDtos);
                return sortDtos;


            }else {
                log.error("初始化失败，请重试");
                return null;
            }
        }else {
            List<SortDto> sortDtos = querySortByViews(zsetKey);
            log.info("排序的数据为：{}",sortDtos);
            return sortDtos;

        }
    }

    public Boolean  prepareData(String zsetKey,    HashMap<Integer, Long> objectObjectHashMap){
        Set<Integer> ids = objectObjectHashMap.keySet();
        //初始化
        initZset(zsetKey,ids);
        //添加数据
        addZset(zsetKey,objectObjectHashMap);
        return true;


    }
    //初始化
    public void initZset(String key, Set<Integer> ids){
        //轻触对应的id
        redisTemplate.delete(key);
        Set<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<>();
        for (Integer s : ids) {
            tuples.add(new DefaultTypedTuple<>(s, 0D));
        }
        log.info("Zset排行榜初始化完成,初始化Set为:{}",tuples);
        Long add = redisTemplate.opsForZSet().add(key, tuples);
        System.out.println("初始化 ： " + add + "条数据");
    }
   //添加数据
    public void addZset(String key,HashMap<Integer, Long> objectObjectHashMap){
        Set<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<>();
        for (Map.Entry<Integer, Long> entry : objectObjectHashMap.entrySet()) {
            tuples.add(new DefaultTypedTuple<>(entry.getKey(), Double.valueOf(entry.getValue())));
        }
        Long add = redisTemplate.opsForZSet().add(key, tuples);
        log.info("成功添加 {} 条数据到排行榜", add);

    }
    public boolean keyExists(String key) {
        return redisTemplate.hasKey(key);
    }
    //获得排序后的数据
    public  List<SortDto> querySortByViews(String key){
        Set<ZSetOperations.TypedTuple<Object>> reverseRangeWithScoresIncome = redisTemplate.opsForZSet().reverseRangeWithScores(key, 0, 9);
        //使用stream流优化
        List<SortDto> countList = reverseRangeWithScoresIncome.stream()
                .map(tuple -> {
                    SortDto sortDto = new SortDto();
                    Integer id = (Integer) tuple.getValue();
                    Double score = tuple.getScore();
                    long l = score.longValue();
                    sortDto.setBlogId(id);
                    sortDto.setBlogViews(l);
                   log.info("BlogID为:{},浏览量为:{}",id,l);
                    return sortDto;
                })
                .collect(Collectors.toList());
        return countList;

    }



}
